﻿
using EmperialApps.WeatherSpark.Data;
using EmperialApps.WeatherSpark.Service.Internal;
using System;
using System.Diagnostics;

namespace EmperialApps.WeatherSpark.Service {

    /// <summary>A subscription service for tracking weather updates.</summary>
    public class WeatherService : IWeatherService {

        /// <inheritdoc/>
        public string Subscribe( Guid deviceId, double latitude, double longitude, string channelUri ) {
            return this.Subscribe2( deviceId, latitude, longitude, null, channelUri );
        }

        /// <inheritdoc/>
        public string Subscribe2( Guid deviceId, double latitude, double longitude, string preferredUrl, string channelUri ) {
            // Try to parse the channel URI.
            Uri uri;
            if( channelUri == null )
                uri = null;
            else if( !Uri.TryCreate( channelUri, UriKind.Absolute, out uri ) )
                return "-Invalid channel URI.";

            // Get the URI for any existing data.
            var account = StorageAccount.Current;
            var location = new Coordinate( latitude, longitude );
            TraceEventType.Verbose.Trace( "Subscribe request for {0} [{1}]", location, preferredUrl );
            string forecastUrl = account.Aggregator.GetUrl( location, preferredUrl );

            // If data not present, save subscription and send a download request.
            if( forecastUrl.Length == 0 ) {
                if( uri == null )
                    forecastUrl = "-Forecast not present on server.";
                else
                    account.Subscriptions.Add( new Subscription( location, deviceId, uri ) );

                account.SendDownloadRequest( location );
            }

            TraceEventType.Information.Trace( "Subscribe request for {0} => {1}", location, forecastUrl );
            return forecastUrl;
        }


        /// <inheritdoc/>
        public string Unsubscribe( Guid deviceId, double latitude, double longitude ) {
            // Remove the subscription.
            var location = new Coordinate( latitude, longitude );
            TraceEventType.Verbose.Trace( "Unsubscribe request for " + location );
            var subscription = new Subscription( location, deviceId );

            var account = StorageAccount.Current;
            bool removed = account.Subscriptions.Remove( subscription );

            TraceEventType.Information.Trace( "Unsubscribe request for {0} => {1}", location, removed ? "removed" : "not found" );
            return removed
                 ? "Subscription removed."
                 : "-Subscription not found.";
        }


        /// <inheritdoc/>
        public bool Use( double latitude, double longitude ) {
            var location = new Coordinate( latitude, longitude );
            TraceEventType.Verbose.Trace( "Updating use of " + location );

            var account = StorageAccount.Current;
            var info = new ForecastInfo( location );
            info.SetLastUserRequest( DateTimeOffset.Now );

            bool updated = account.ForecastInfo.Update( info );

            TraceEventType.Information.Trace( "Use of {0} {1}updated.", location, updated ? "" : "was not" );
            return updated;
        }

    }

}
